#include "system.h"

//定义一个485通讯结构体
typedef struct flapp_rs485
{
	uint8_t dis_icon;											//图标标志
	uint8_t rs485_rx_buf[RS485_MOSI_ENUM_END];	
	uint16_t last_slave_err[RS485_MAX];
	flapp_device_type_e device_type;			//主机1从机2
}flapp_rs485_t;

struct flapp_rs485 flapp_485;

/**********************************************************
函数功能：485初始化
入口参数：无
出口参数：无
说	  明 
***********************************************************/ 
void flapp_485_init(void)
{
	uint8_t i;
	flapp_485.device_type = DEVICE_UNKNOWN;
	flapp_485.dis_icon = FALSE;
	for(i = 0;i < RS485_MAX;i++)
	{
		flapp_485.last_slave_err[i] = SLAVE_MARK + i * 100;
	}
}

/**********************************************************
函数功能：485判断主从机函数
入口参数：flapp_dis
出口参数：无
说	  明 
***********************************************************/ 
void flapp_set_device_type(struct flapp_dis app_dis)		//直接设置是主机还是从机就是了
{
	uint8_t part_id[2],res;
	static uint8_t device_slave = FALSE;
	fldrv_i2c_read_byte(ENS210_REG_PART_ID_L,&part_id[0]);
	fldrv_i2c_read_byte(ENS210_REG_PART_ID_H,&part_id[1]);
	if(((part_id[1] << 8) + part_id[0] != ENS210_PARTID) && app_dis.value_air[0] == 0){	//PM25和温湿度都没接为从机
		device_slave++;
		if(device_slave >= ADDR_SLAVE_COUNT){
			flapp_485.device_type = DEVICE_SLAVE;
			res = fldrv_read_slave_addr();
			flapp_set_slave_addr(res);
		}
	}
	else
		flapp_485.device_type = DEVICE_MASTER;
}

void flapp_send_rs485_buf(uint8_t* data,uint8_t len)
{
	RS_485_TX_EN;
	fldrv_uart_send_buf(USART2,data,len);
	RS_485_RX_EN;
}

static void flapp_master_rcv_pro()
{
	uint8_t i;
	if(xQueueReceive(rs485_queue,flapp_485.rs485_rx_buf,0) == pdFALSE)
		return;
	
	for(i = 0;i < RS485_MAX;i++)
	{
		if(flapp_485.last_slave_err[i] % 10000 / 100 == flapp_485.rs485_rx_buf[RS485_MISO_ADDR])
		{
			if(flapp_485.last_slave_err[i] % 100 != flapp_485.rs485_rx_buf[RS485_MISO_ERR])
			{
				uint8_t ion_err,fan_err;
				ion_err = GET_BIT(flapp_485.rs485_rx_buf[RS485_MISO_ERR],DEVICE_ERROR_ION);
				fan_err = GET_BIT(flapp_485.rs485_rx_buf[RS485_MISO_ERR],DEVICE_ERROR_FAN);
				flapp_485.last_slave_err[i] = flapp_485.rs485_rx_buf[RS485_MISO_ADDR] * 100 + \
																			ion_err* 20 + fan_err;
				flapp_set_slave_err_report(flapp_485.last_slave_err[i]);
			}
			break;
		}
	}
}
/**********************************************************
函数功能：485主机处理函数
入口参数：flapp_dis
出口参数：无
说	  明 
***********************************************************/ 
static void flapp_rs485_master_pro(struct flapp_dis get_dis_content)
{
	
	static uint8_t rs485_id_count = FALSE,rs485_tmr_cnt = FALSE;
	
	uint8_t master_send_buf[RS485_MOSI_ENUM_END] = {0};

	rs485_tmr_cnt++;
	flapp_master_rcv_pro();
	if(rs485_tmr_cnt < 5)				//500ms一次轮询
		return;
	rs485_tmr_cnt = FALSE;
	rs485_id_count++;
	if(rs485_id_count > RS485_MAX)
	{
		rs485_id_count = FALSE;
	}
	master_send_buf[RS485_MOSI_HEAD_H] 		= DEFAULT_RS485_HEAD1;
	master_send_buf[RS485_MOSI_HEAD_L] 		= DEFAULT_RS485_HEAD2;
	master_send_buf[RS485_MOSI_DEVICE]	 	= flapp_485.device_type;
	master_send_buf[RS485_MOSI_ADDR]	 		= rs485_id_count;
	master_send_buf[RS485_MOSI_ICON] 			= BIT0 * get_dis_content.flag_auto + \
																					BIT1 * get_dis_content.flag_ion + \
																					BIT2 * (1 - get_dis_content.flag_filter) + \
																					BIT3 * get_dis_content.flag_net;
	master_send_buf[RS485_MOSI_AIR_LEV]		= get_dis_content.air_level;
	master_send_buf[RS485_MOSI_FAN_SPEED]	= get_dis_content.value_fan;
	master_send_buf[RS485_MOSI_TEMP_H]		= get_dis_content.val_t_h_buf[0] >> 8;
	master_send_buf[RS485_MOSI_TEMP_L]		= get_dis_content.val_t_h_buf[0];
	master_send_buf[RS485_MOSI_HUM_H]			= get_dis_content.val_t_h_buf[1] >> 8;
	master_send_buf[RS485_MOSI_HUM_L]			= get_dis_content.val_t_h_buf[1];
	master_send_buf[RS485_MOSI_PM25_H]		= get_dis_content.value_air[0] >> 8;
	master_send_buf[RS485_MOSI_PM25_L]		= get_dis_content.value_air[0];
	master_send_buf[RS485_MOSI_VOC_H]			= get_dis_content.value_air[1] >> 8;
	master_send_buf[RS485_MOSI_VOC_L]			= get_dis_content.value_air[1];
	master_send_buf[RS485_MOSI_RES1]			= 0;
	master_send_buf[RS485_MOSI_RES2]			= 0;
	master_send_buf[RS485_MOSI_CHECKNUM]  = fldrv_check_sum(master_send_buf,RS485_MOSI_CHECKNUM);
	flapp_send_rs485_buf(master_send_buf,RS485_MOSI_ENUM_END);
}

/**********************************************************
函数功能：485从机处理函数
入口参数：flapp_dis
出口参数：无
说	  明 
***********************************************************/ 
static void flapp_rs485_slave_pro(struct flapp_dis get_dis_buf)
{
	uint16_t air_queue[2] = {0};
	int16_t th_queue[2] = {0};
	uint8_t remote_queue[REMOTE_NUM] = {0};
	uint8_t slave_send_buf[RS485_MISO_ENUM_END];
	if(xQueueReceive(rs485_queue,flapp_485.rs485_rx_buf,0) == pdTRUE)
	{
		remote_queue[REMOTE_VAILD] 				= GET_BIT(flapp_485.rs485_rx_buf[RS485_MOSI_ICON],ICON_NET) * BIT5 + 0x0f;
		remote_queue[REMOTE_AUTO]					= GET_BIT(flapp_485.rs485_rx_buf[RS485_MOSI_ICON],ICON_AUTO);
		remote_queue[REMOTE_ION]					= GET_BIT(flapp_485.rs485_rx_buf[RS485_MOSI_ICON],ICON_ION);
		remote_queue[REMOTE_FILTER_RESET]	= (TRUE - GET_BIT(flapp_485.rs485_rx_buf[RS485_MOSI_ICON],ICON_FILTER));
		remote_queue[REMOTE_FAN_SPEED]		= flapp_485.rs485_rx_buf[RS485_MOSI_FAN_SPEED];
		xQueueSend(remote_con_queue,remote_queue,0);
		
		th_queue[0] = (flapp_485.rs485_rx_buf[RS485_MOSI_TEMP_H] << 8) + flapp_485.rs485_rx_buf[RS485_MOSI_TEMP_L];
		th_queue[1]	= (flapp_485.rs485_rx_buf[RS485_MOSI_HUM_H] << 8) + flapp_485.rs485_rx_buf[RS485_MOSI_HUM_L];
		xQueueSend(t_h_queue,th_queue,0);
		
		air_queue[0] = (flapp_485.rs485_rx_buf[RS485_MOSI_PM25_H] << 8) + flapp_485.rs485_rx_buf[RS485_MOSI_PM25_L];
		air_queue[1]	= (flapp_485.rs485_rx_buf[RS485_MOSI_VOC_H] << 8) + flapp_485.rs485_rx_buf[RS485_MOSI_VOC_L];
		xQueueSend(air_quality_queue,air_queue,0);
		
		vTaskDelay(TASK_UART_SEND_DLY);	//收发串口间隔点时间效果更好

		slave_send_buf[RS485_MISO_HEAD_H] 		= DEFAULT_RS485_HEAD1;
		slave_send_buf[RS485_MISO_HEAD_L] 		= DEFAULT_RS485_HEAD2;
		slave_send_buf[RS485_MISO_DEVICE]	 		= flapp_485.device_type;
		slave_send_buf[RS485_MISO_ADDR]	 			= get_dis_buf.slave_addr;
		slave_send_buf[RS485_MISO_ERR] 				= get_dis_buf.slave_err;
		slave_send_buf[RS485_MISO_RES1]				= 0;
		slave_send_buf[RS485_MISO_RES2] 			= 0;
		slave_send_buf[RS485_MISO_CHECKNUM]		= fldrv_check_sum(slave_send_buf,RS485_MISO_CHECKNUM);
		if(flapp_485.rs485_rx_buf[RS485_MOSI_ADDR] == get_dis_buf.slave_addr)
			flapp_send_rs485_buf(slave_send_buf,RS485_MISO_ENUM_END);
	}
}


/**********************************************************
函数功能：485任务运行函数
入口参数：无
出口参数：无
说	  明 
***********************************************************/ 
void flapp_rs485_run(void)
{
	struct flapp_dis get_dis_content;
	get_dis_content = flapp_get_device_status();
	if(flapp_485.device_type == DEVICE_UNKNOWN)
	{
		flapp_set_device_type(get_dis_content);
	}
	
	switch(flapp_485.device_type)
	{
		case DEVICE_UNKNOWN:
			break;
		case DEVICE_MASTER:
			flapp_rs485_master_pro(get_dis_content);
			break;
		case DEVICE_SLAVE:
			flapp_rs485_slave_pro(get_dis_content);
			break;
	}
}

/**********************************************************
函数功能：获取485是从机还是主机
入口参数：无
出口参数：flapp_device_type_e
说	  明 
***********************************************************/ 
flapp_device_type_e flapp_get_device_type(void)
{
	return flapp_485.device_type;
}
